unit UltimateSheduler_SetupForm;

interface

uses
  UltimateSheduler_Defines,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, Grids, XPMan, ComCtrls, TabNotBk, JvDialogs,
  Spin;

type
  TUSSetupForm = class(TForm)
    BitBtn1: TBitBtn;
    BitBtn2: TBitBtn;
    XPManifest1: TXPManifest;
    TN1: TTabbedNotebook;
    SG_Tasks: TStringGrid;
    SB_AddTask: TSpeedButton;
    SB_DelTask: TSpeedButton;
    SB_EditTask: TSpeedButton;
    SB_AddAG: TSpeedButton;
    SB_DelAG: TSpeedButton;
    SB_EditAG: TSpeedButton;
    SB_AddRule: TSpeedButton;
    SB_DelRule: TSpeedButton;
    SB_EditRule: TSpeedButton;
    LB_Rules: TListBox;
    LB_Actions: TListBox;
    SB_SaveTask: TSpeedButton;
    SB_LoadTask: TSpeedButton;
    OD1: TJvOpenDialog;
    SD1: TJvSaveDialog;
    SB_SaveRule: TSpeedButton;
    SB_LoadRule: TSpeedButton;
    SB_SaveAG: TSpeedButton;
    SB_LoadAG: TSpeedButton;
    GB_Log: TGroupBox;
    CB_LogEnabled: TCheckBox;
    CBX_LogSave: TComboBox;
    Label1: TLabel;
    CB_LogDM: TCheckBox;
    Label2: TLabel;
    SE_LogSize: TSpinEdit;
    CB_Silent: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure SG_TasksClick(Sender: TObject);
    procedure SB_AddTaskClick(Sender: TObject);
    procedure SB_DelTaskClick(Sender: TObject);
    procedure SB_EditTaskClick(Sender: TObject);
    procedure LB_RulesClick(Sender: TObject);
    procedure SB_AddRuleClick(Sender: TObject);
    procedure SB_DelRuleClick(Sender: TObject);
    procedure SB_EditRuleClick(Sender: TObject);
    procedure SB_AddAGClick(Sender: TObject);
    procedure SB_DelAGClick(Sender: TObject);
    procedure SB_EditAGClick(Sender: TObject);
    procedure SB_SaveTaskClick(Sender: TObject);
    procedure SB_LoadTaskClick(Sender: TObject);
    procedure SB_SaveRuleClick(Sender: TObject);
    procedure SB_LoadRuleClick(Sender: TObject);
    procedure SB_SaveAGClick(Sender: TObject);
    procedure SB_LoadAGClick(Sender: TObject);
    procedure LB_ActionsClick(Sender: TObject);
    procedure CB_LogEnabledClick(Sender: TObject);
    procedure CB_LogDMClick(Sender: TObject);
    procedure CBX_LogSaveChange(Sender: TObject);
    procedure SE_LogSizeChange(Sender: TObject);
    procedure CB_SilentClick(Sender: TObject);
  private
    { Private declarations }
    FSettings: Settings;
    procedure SetSettings(NewSettings: Settings);
    procedure Translate;
    //
    procedure RefreshTasks;
    procedure CheckTasks;
    procedure RefreshRules;
    procedure CheckRules;
    procedure RefreshActions;
    procedure CheckActions;
  public
    { Public declarations }
    property formSettings: Settings read FSettings write SetSettings;
  end;

  TAfterCloseProcedure = procedure of object;

var
  SF: TUSSetupForm = nil;

function IsFormClosed(var AForm: TUSSetupForm; AfterClose: TAfterCloseProcedure = nil): Boolean;

implementation

{$R *.dfm}

uses
 gnugettext,
 Math,
 UltimateSheduler_TaskForm,
 UltimateSheduler_RuleForm,
 UltimateSheduler_ActionGroupForm;

const
 msgDel = 'Are you sure to delete %s "%s" ?';
 msgLoad = 'Load %s';
 msgSave = 'Save %s';
 msgLoadErr = 'Error occured when loading %s from file "%s". %s is not loaded.';
 msgReplace = '%s with title "%s" already exists. Do you want to replace it with loaded?';

procedure BitBtnClick(AForm: TUSSetupForm; const BitBtn: TBitBtn);
begin
 if Assigned(AForm) and Assigned(BitBtn) then
  begin
   if BitBtn.Owner=AForm then
    begin
     AForm.ModalResult:=BitBtn.ModalResult;
     if not (fsModal in AForm.FormState) then
       AForm.Close;
    end;
  end;
end;

function IsFormClosed(var AForm: TUSSetupForm; AfterClose: TAfterCloseProcedure = nil): Boolean;
begin
 Result:=false;
 if Assigned(AForm) and (not AForm.Showing) then
  begin
   if AForm.ModalResult=mrOK then
    begin
     if Assigned(AfterClose) then
       AfterClose;
    end;
   FreeAndNil(AForm);
   Result:=true;
  end;
end;

procedure TUSSetupForm.FormCreate(Sender: TObject);
begin
 TP_IgnoreClass(TTabbedNotebook);
 TranslateComponent(self);
 //ShowMessage('Form translated.'); //debug
 Translate; //some items are not translated automatically
 //
 //ShowMessage('All form translated.'); //debug
 FSettings:=Settings.Create;
 //ShowMessage('Settings created.'); //debug
end;

procedure TUSSetupForm.FormDestroy(Sender: TObject);
begin
 FreeAndNil(FSettings);
end;

procedure TUSSetupForm.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
 //
end;

procedure TUSSetupForm.BitBtn1Click(Sender: TObject);
begin
 BitBtnClick(Self, Sender as TBitBtn);
end;

procedure TUSSetupForm.BitBtn2Click(Sender: TObject);
begin
 BitBtnClick(Self, Sender as TBitBtn);
end;

procedure TUSSetupForm.Translate;
begin
 SG_Tasks.Cells[0, 0]:=_('Title');
 SG_Tasks.ColWidths[0]:=100;
 SG_Tasks.Cells[1, 0]:=_('Launch');
 SG_Tasks.ColWidths[1]:=100;
 SG_Tasks.Cells[2, 0]:=_('Last launch');
 SG_Tasks.ColWidths[2]:=100;
 SG_Tasks.Cells[3, 0]:=_('Next launch');
 SG_Tasks.ColWidths[3]:=100;
 //
 TN1.Pages[0]:=_('Tasks');
 TN1.Pages[1]:=_('Rules');
 TN1.Pages[2]:=_('Action groups');
end;

procedure TUSSetupForm.SetSettings(NewSettings: Settings);
begin
 //FSettings.Rules.Clear;
 FSettings.Assign(NewSettings);
 // Here controls must be syncronized with settings
 RefreshTasks;
 RefreshRules;
 RefreshActions;
 //
 CB_LogEnabled.Checked:=FSettings.LogEnabled;
 CB_LogDM.Checked:=FSettings.LogDM;
 CB_Silent.Checked:=FSettings.Silent;
 FSettings.LogSave:=FSettings.LogSave mod 5;
 CBX_LogSave.ItemIndex:=FSettings.LogSave;
 SE_LogSize.Value:=FSettings.LogSize;
end;

procedure TUSSetupForm.RefreshTasks;
 var
  i: Integer;
begin
 SG_Tasks.RowCount:=Max(2, FSettings.Tasks.Count+1);
 if FSettings.Tasks.Count<1 then
  begin
   SG_Tasks.Cells[0, 1]:='';
   SG_Tasks.Cells[1, 1]:='';
   SG_Tasks.Cells[2, 1]:='';
   SG_Tasks.Cells[3, 1]:='';
  end
 else
  begin
   for i:=0 to FSettings.Tasks.Count-1 do
    begin
     SG_Tasks.Cells[0, i+1]:=FSettings.Tasks[i].Title;
     FSettings.Tasks[i].Enabled:=FSettings.Tasks[i].Enabled and ((FSettings.Tasks[i].RuleTitle='') or (FSettings.Rules.IndexOfTitle(FSettings.Tasks[i].RuleTitle)>=0)) and (FSettings.ActionGroups.IndexOfTitle(FSettings.Tasks[i].ActionsTitle)>=0);
     if FSettings.Tasks[i].Enabled then
       SG_Tasks.Cells[1, i+1]:=GetLaunchTypeTitle(FSettings.Tasks[i].LaunchType)
     else
       SG_Tasks.Cells[1, i+1]:=GetLaunchTypeTitle(FSettings.Tasks[i].LaunchType)+_('(disabled)');
     if FSettings.Tasks[i].LastLaunch=0 then
       SG_Tasks.Cells[2, i+1]:=_('Never')
     else
       SG_Tasks.Cells[2, i+1]:=DateTimeToStr(FSettings.Tasks[i].LastLaunch);
     if FSettings.Tasks[i].NextLaunch=0 then
      begin
       case FSettings.Tasks[i].LaunchType of
        ultDemand: SG_Tasks.Cells[3, i+1]:=_(ultDemandTitle);
        ultEvent: SG_Tasks.Cells[3, i+1]:=_(ultEventTitle);
        else SG_Tasks.Cells[3, i+1]:=_('Never')
        end;
      end
     else
       SG_Tasks.Cells[3, i+1]:=DateTimeToStr(FSettings.Tasks[i].NextLaunch);
    end;
  end;
 CheckTasks; 
end;

procedure TUSSetupForm.CheckTasks;
begin
 SB_DelTask.Enabled:=(SG_Tasks.Selection.Top>0) and (SG_Tasks.Selection.Top<=FSettings.Tasks.Count);
 SB_EditTask.Enabled:=SB_DelTask.Enabled;
 SB_SaveTask.Enabled:=SB_DelTask.Enabled;
end;

procedure TUSSetupForm.SG_TasksClick(Sender: TObject);
begin
 CheckTasks;
end;

procedure TUSSetupForm.SB_AddTaskClick(Sender: TObject);
 var
  TF: TUSTaskForm;
begin
 TF:=TUSTaskForm.Create(Self);
 TF.Rules:=FSettings.Rules;
 TF.ActionGroups:=FSettings.ActionGroups;
 TF.TaskTitles:=FSettings.Tasks.ListOfTitles;
 if TF.ShowModal=mrOK then
  begin
   FSettings.Tasks.Add.Assign(TF.aTask);
   RefreshTasks;
   if TF.RulesChanged then
    begin
     FSettings.Rules.Assign(TF.Rules);
     RefreshRules;
    end;
   if TF.ActionsChanged then
    begin
     FSettings.ActionGroups.Assign(TF.ActionGroups);
     RefreshActions;
    end;
  end;
 FreeAndNil(TF);
end;

procedure TUSSetupForm.SB_DelTaskClick(Sender: TObject);
 var
  i: Integer;
begin
 i:=SG_Tasks.Selection.Top-1;
 if (i>=0) and (i<FSettings.Tasks.Count) then
  begin
   if MessageDlg(Format(_(msgDel), [_(sTask), FSettings.Tasks[i].Title]), mtConfirmation, [mbYes, mbNo], 0)=mrYes then
    begin
     FSettings.Tasks.Delete(i);
     RefreshTasks;
    end;
  end;
end;

procedure TUSSetupForm.SB_EditTaskClick(Sender: TObject);
 var
  i: Integer;
  TF: TUSTaskForm;
begin
 i:=SG_Tasks.Selection.Top-1;
 if (i>=0) and (i<FSettings.Tasks.Count) then
  begin
   TF:=TUSTaskForm.Create(Self);
   TF.Rules:=FSettings.Rules;
   TF.ActionGroups:=FSettings.ActionGroups;
   TF.TaskTitles:=FSettings.Tasks.ListOfTitles;
   TF.aTask:=FSettings.Tasks[i];
   TF.ThisTask:=FSettings.Tasks[i].Title;
   if TF.ShowModal=mrOK then
    begin
     FSettings.Tasks[i].Assign(TF.aTask);
     RefreshTasks;
     if TF.RulesChanged then
      begin
       FSettings.Rules.Assign(TF.Rules);
       RefreshRules;
      end;
     if TF.ActionsChanged then
      begin
       FSettings.ActionGroups.Assign(TF.ActionGroups);
       RefreshActions;
      end;
    end;
   FreeAndNil(TF);
  end;
end;

procedure TUSSetupForm.RefreshRules;
 var
  i: Integer;
begin
 LB_Rules.Clear;
 for i:=0 to FSettings.Rules.Count-1 do
   LB_Rules.Items.Add(FSettings.Rules[i].Title);
 CheckRules;
end;

procedure TUSSetupForm.CheckRules;
begin
 SB_DelRule.Enabled:=(LB_Rules.ItemIndex>=0) and (LB_Rules.ItemIndex<FSettings.Rules.Count);
 SB_EditRule.Enabled:=SB_DelRule.Enabled;
 SB_SaveRule.Enabled:=SB_DelRule.Enabled;
end;

procedure TUSSetupForm.LB_RulesClick(Sender: TObject);
begin
 CheckRules;
end;

procedure TUSSetupForm.SB_AddRuleClick(Sender: TObject);
 var
  RF: TUSRuleForm;
begin
 RF:=TUSRuleForm.Create(Self);
 RF.RuleTitles:=FSettings.Rules.ListOfTitles;
 if RF.ShowModal=mrOK then
  begin
   FSettings.Rules.Add(myFunction).Assign(RF.myRule);
   RefreshRules;
  end;
 FreeAndNil(RF);
end;

procedure TUSSetupForm.SB_DelRuleClick(Sender: TObject);
 var
  i: Integer;
begin
 i:=LB_Rules.ItemIndex;
 if (i>=0) and (i<FSettings.Rules.Count) then
  begin
   if MessageDlg(Format(_(msgDel), [_(sRule), FSettings.Rules[i].Title]), mtConfirmation, [mbYes, mbNo], 0)=mrYes then
    begin
     FSettings.Rules.Delete(i);
     RefreshRules;
    end;
  end;
end;

procedure TUSSetupForm.SB_EditRuleClick(Sender: TObject);
 var
  i: Integer;
  RF: TUSRuleForm;
begin
 i:=LB_Rules.ItemIndex;
 if (i>=0) and (i<FSettings.Rules.Count) then
  begin
   RF:=TUSRuleForm.Create(Self);
   RF.myRule:=FSettings.Rules[i];
   RF.RuleTitles:=FSettings.Rules.ListOfTitles;
   if RF.ShowModal=mrOK then
    begin
     FSettings.Rules[i].Assign(RF.myRule);
     RefreshRules;
    end;
   FreeAndNil(RF);
  end;
end;

procedure TUSSetupForm.RefreshActions;
 var
  i: Integer;
begin
 LB_Actions.Clear;
 for i:=0 to FSettings.ActionGroups.Count-1 do
   LB_Actions.Items.Add(FSettings.ActionGroups[i].Title);
 CheckActions;
end;

procedure TUSSetupForm.CheckActions;
begin
 SB_DelAG.Enabled:=(LB_Actions.ItemIndex>=0) and (LB_Actions.ItemIndex<FSettings.ActionGroups.Count);
 SB_EditAG.Enabled:=SB_DelAG.Enabled;
 SB_SaveAG.Enabled:=SB_DelAG.Enabled;
end;

procedure TUSSetupForm.SB_AddAGClick(Sender: TObject);
 var
  AGF: TUSActionGroupForm;
begin
 AGF:=TUSActionGroupForm.Create(Self);
 AGF.ActionTitles:=FSettings.ActionGroups.ListOfTitles;
 if AGF.ShowModal=mrOK then
  begin
   FSettings.ActionGroups.Add.Assign(AGF.myActionGroup);
   RefreshActions;
  end;
 FreeAndNil(AGF);
end;

procedure TUSSetupForm.SB_DelAGClick(Sender: TObject);
 var
  i: Integer;
begin
 i:=LB_Actions.ItemIndex;
 if (i>=0) and (i<FSettings.ActionGroups.Count) then
  begin
   if MessageDlg(Format(_(msgDel), [_(sAG), FSettings.ActionGroups[i].Title]), mtConfirmation, [mbYes, mbNo], 0)=mrYes then
    begin
     FSettings.ActionGroups.Delete(i);
     RefreshActions;
    end;
  end;
end;

procedure TUSSetupForm.SB_EditAGClick(Sender: TObject);
 var
  i: Integer;
  AGF: TUSActionGroupForm;
begin
 i:=LB_Rules.ItemIndex;
 if (i>=0) and (i<FSettings.ActionGroups.Count) then
  begin
   AGF:=TUSActionGroupForm.Create(Self);
   AGF.myActionGroup:=FSettings.ActionGroups[i];
   AGF.ActionTitles:=FSettings.ActionGroups.ListOfTitles;
   if AGF.ShowModal=mrOK then
    begin
     FSettings.ActionGroups[i].Assign(AGF.myActionGroup);
     RefreshActions;
    end;
   FreeAndNil(AGF);
  end;
end;

procedure TUSSetupForm.SB_SaveTaskClick(Sender: TObject);
 var
  i: Integer;
  ST: SingleTask;
begin
 i:=SG_Tasks.Selection.Top-1;
 if (i>=0) and (i<FSettings.Tasks.Count) then
  begin
   SD1.Title:=Format(msgSave, [_(sTask)]);
   SD1.Filter:=_(TasksFilter);
   SD1.FilterIndex:=1;
   SD1.DefaultExt:=TaskExt;
   SD1.FileName:=PluginsPath+FSettings.Tasks[i].Title+TaskExt;
   if SD1.Execute then
    begin
     if not SameText(ExtractFileExt(SD1.FileName), TaskExt) then
       SD1.FileName:=SD1.FileName+TaskExt;
     ST:=SingleTask.Create;
     ST.aTask.Assign(FSettings.Tasks[i]);
     XML.Serialize(ST, SD1.FileName);
     FreeAndNil(ST);
    end;
  end;
end;

procedure TUSSetupForm.SB_LoadTaskClick(Sender: TObject);
 var
  i: Integer;
  ST: SingleTask;
begin
 OD1.Title:=Format(msgLoad, [_(sTask)]);
 OD1.Filter:=_(TasksFilter)+'|'+_(AllFilesFilter);
 OD1.FilterIndex:=1;
 OD1.DefaultExt:=TaskExt;
 OD1.InitialDir:=PluginsPath;
 if OD1.Execute then
  begin
   ST:=SingleTask.Create;
   if XML.DeSerialize(ST, OD1.FileName)=0 then
    begin
     i:=FSettings.Tasks.IndexOfTitle(ST.aTask.Title);
     if i<0 then
       FSettings.Tasks.Add.Assign(ST.aTask)
     else
      begin
       if MessageDlg(Format(_(msgReplace), [_(sTaskC), ST.aTask.Title]), mtWarning, [mbYes, mbNo], 0)=mrYes then
         FSettings.Tasks[i].Assign(ST.aTask);
      end;
     RefreshTasks;
    end
   else
     MessageDlg(Format(_(msgLoadErr), [OD1.FileName, _(sTask), _(sTaskC)]), mtError, [mbOK], 0);
   FreeAndNil(ST);
  end;
end;

procedure TUSSetupForm.SB_SaveRuleClick(Sender: TObject);
 var
  i: Integer;
  ST: SingleRule;
begin
 i:=LB_Rules.ItemIndex;
 if (i>=0) and (i<FSettings.Rules.Count) then
  begin
   SD1.Title:=Format(msgSave, [_(sRule)]);
   SD1.Filter:=_(RulesFilter);
   SD1.FilterIndex:=1;
   SD1.DefaultExt:=RuleExt;
   SD1.FileName:=PluginsPath+FSettings.Rules[i].Title+RuleExt;
   if SD1.Execute then
    begin
     if not SameText(ExtractFileExt(SD1.FileName), RuleExt) then
       SD1.FileName:=SD1.FileName+RuleExt;
     ST:=SingleRule.Create;
     ST.aRule.Assign(FSettings.Rules[i]);
     XML.Serialize(ST, SD1.FileName);
     FreeAndNil(ST);
    end;
  end;
end;

procedure TUSSetupForm.SB_LoadRuleClick(Sender: TObject);
 var
  i: Integer;
  ST: SingleRule;
begin
 OD1.Title:=Format(msgLoad, [_(sRule)]);
 OD1.Filter:=_(RulesFilter)+'|'+_(AllFilesFilter);
 OD1.FilterIndex:=1;
 OD1.DefaultExt:=RuleExt;
 OD1.InitialDir:=PluginsPath;
 if OD1.Execute then
  begin
   ST:=SingleRule.Create;
   if XML.DeSerialize(ST, OD1.FileName)=0 then
    begin
     i:=FSettings.Rules.IndexOfTitle(ST.aRule.Title);
     if i<0 then
       FSettings.Rules.Add(myFunction).Assign(ST.aRule)
     else
      begin
       if MessageDlg(Format(_(msgReplace), [_(sRuleC), ST.aRule.Title]), mtWarning, [mbYes, mbNo], 0)=mrYes then
         FSettings.Rules[i].Assign(ST.aRule);
      end;
     RefreshTasks;
    end
   else
     MessageDlg(Format(_(msgLoadErr), [OD1.FileName, _(sRule), _(sRuleC)]), mtError, [mbOK], 0);
   FreeAndNil(ST);
  end;
end;

procedure TUSSetupForm.SB_SaveAGClick(Sender: TObject);
 var
  i: Integer;
  ST: SingleActionGroup;
begin
 i:=LB_Actions.ItemIndex;
 if (i>=0) and (i<FSettings.ActionGroups.Count) then
  begin
   SD1.Title:=Format(msgSave, [_(sAG)]);
   SD1.Filter:=_(ActionsFilter);
   SD1.FilterIndex:=1;
   SD1.DefaultExt:=AGExt;
   SD1.FileName:=PluginsPath+FSettings.ActionGroups[i].Title+AGExt;
   if SD1.Execute then
    begin
     if not SameText(ExtractFileExt(SD1.FileName), AGExt) then
       SD1.FileName:=SD1.FileName+AGExt;
     ST:=SingleActionGroup.Create;
     ST.anActionGroup.Assign(FSettings.ActionGroups[i]);
     XML.Serialize(ST, SD1.FileName);
     FreeAndNil(ST);
    end;
  end;
end;

procedure TUSSetupForm.SB_LoadAGClick(Sender: TObject);
 var
  i: Integer;
  ST: SingleActionGroup;
begin
 OD1.Title:=Format(msgLoad, [_(sAG)]);
 OD1.Filter:=_(ActionsFilter)+'|'+_(AllFilesFilter);
 OD1.FilterIndex:=1;
 OD1.DefaultExt:=AGExt;
 OD1.InitialDir:=PluginsPath;
 if OD1.Execute then
  begin
   ST:=SingleActionGroup.Create;
   if XML.DeSerialize(ST, OD1.FileName)=0 then
    begin
     i:=FSettings.ActionGroups.IndexOfTitle(ST.anActionGroup.Title);
     if i<0 then
       FSettings.ActionGroups.Add.Assign(ST.anActionGroup)
     else
      begin
       if MessageDlg(Format(_(msgReplace), [_(sAGC), ST.anActionGroup.Title]), mtWarning, [mbYes, mbNo], 0)=mrYes then
         FSettings.ActionGroups[i].Assign(ST.anActionGroup);
      end;
     RefreshTasks;
    end
   else
     MessageDlg(Format(_(msgLoadErr), [OD1.FileName, _(sAG), _(sAGC)]), mtError, [mbOK], 0);
   FreeAndNil(ST);
  end;
end;

procedure TUSSetupForm.LB_ActionsClick(Sender: TObject);
begin
 CheckActions;
end;

procedure TUSSetupForm.CB_LogEnabledClick(Sender: TObject);
begin
 FSettings.LogEnabled:=CB_LogEnabled.Checked;
end;

procedure TUSSetupForm.CB_LogDMClick(Sender: TObject);
begin
 FSettings.LogDM:=CB_LogDM.Checked;
end;

procedure TUSSetupForm.CBX_LogSaveChange(Sender: TObject);
begin
 FSettings.LogSave:=CBX_LogSave.ItemIndex;
end;

procedure TUSSetupForm.SE_LogSizeChange(Sender: TObject);
begin
 FSettings.LogSize:=SE_LogSize.Value;
end;

procedure TUSSetupForm.CB_SilentClick(Sender: TObject);
begin
 FSettings.Silent:=CB_Silent.Checked;
end;

end.
